#pragma once
#include "rpc_register.hpp"
#include "rpc_router.hpp"
#include "../client/rpc_client.hpp"
#include "../common/dispatcher.hpp"
#include "rpc_topic.hpp"

namespace MyRpc
{
    namespace server
    {
        // 服务注册类 注册中心
        class RegisterServer
        {
        public:
            using ptr = std::shared_ptr<RegisterServer>;
            RegisterServer(int port)
                :_pdmanage(std::make_shared<ProviderDiscoveryManage>())
            {
                auto cb = std::bind(&ProviderDiscoveryManage::onServiceRequest, _pdmanage.get(), std::placeholders::_1, std::placeholders::_2);
                disp->Register<ServiceRequest>(MType::REQ_SERVICE, cb);
                // 创建服务端
                _server = ServerFactory::create(port);
                auto server_cb = std::bind(&Dispatcher::OnMessage, disp.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallBack(server_cb);
                _server->setCloseCallBack(std::bind(&RegisterServer::shutDown, this, std::placeholders::_1));
            }
            void start()
            {
                _server->start();
            }
        private:
            void shutDown(const BaseConnection::ptr& conn)
            {
                // 关闭连接
                return _pdmanage->shutDown(conn);
            }
        private:
            ProviderDiscoveryManage::ptr _pdmanage;
            BaseServer::ptr _server;
        };

        class RpcServer
        {
        public:
            using ptr = std::shared_ptr<RpcServer>;
            // 第一个地址是服务端的地址 外部访问的地址
            // 第二个地址是注册中心的地址 注册服务的地址
            RpcServer(const Addr& server_addr, bool enableRegister = false, const Addr& register_addr = Addr()) 
                :_enableRegister(enableRegister)
                ,_router(std::make_shared<RpcRouter>())
                ,_access_addr(server_addr)
            {
                if(enableRegister)
                {
                    // 开启服务注册中心操作
                    _register_client = std::make_shared<client::ProviderClient>(register_addr.first, register_addr.second);
                }

                _server = ServerFactory::create(server_addr.second);
                disp->Register<RpcRequest>(MType::REQ_RPC, std::bind(&RpcRouter::OnRpcMessage, _router.get(),
                                                                             std::placeholders::_1, std::placeholders::_2));
                auto cb = std::bind(&Dispatcher::OnMessage, disp.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallBack(cb);
            }
            void registerMethod(const ServiceDescribe::ptr& msg)
            {
                _router->registerMethod(msg);
                // LOG(DEBUGLEVEL, "服务注册成功!");
                if(_enableRegister)
                {
                    // 开启了服务注册
                    _register_client->registerMethod(msg->method(), _access_addr);
                }
            }
            void start()
            {
                _server->start();
            }
        private:
            bool _enableRegister;
            Addr _access_addr;
            client::ProviderClient::ptr _register_client;  // 用来注册服务的客户端
            RpcRouter::ptr _router;
            BaseServer::ptr _server;
        };
        
        // 用来提供主题服务的服务器
        class TopicServer
        {
        public:
            using ptr = std::shared_ptr<TopicServer>;
            TopicServer(int port)
                :_topic_manage(std::make_shared<TopicManage>())
            {
                auto cb = std::bind(&TopicManage::OnRpcMessage, _topic_manage.get(), std::placeholders::_1, std::placeholders::_2);
                disp->Register<TopicRequest>(MType::REQ_TOPIC, cb);
                // 创建服务端
                _server = ServerFactory::create(port);
                auto server_cb = std::bind(&Dispatcher::OnMessage, disp.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallBack(server_cb);
                _server->setCloseCallBack(std::bind(&TopicServer::shutDown, this, std::placeholders::_1));
            }
            void start()
            {
                _server->start();
            }
        private:
            void shutDown(const BaseConnection::ptr& conn)
            {
                // 关闭连接
                return _topic_manage->shutDownConntion(conn);
            }
        private:
            TopicManage::ptr _topic_manage;
            BaseServer::ptr _server;
        };
    }
}